﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.MainModule.Entities;
using Domain.MainModule.Branches;
using Domain.Core.Specification;
using Domain.Core;
using Domain.MainModule.BillingInformations;

namespace Application.MainModule.BranchesManagement
{
    public class BranchManagementService: IBranchManagementService, IDisposable
    {
        #region Members

        IBranchRepository _BranchRepository;

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor for BranchService
        /// </summary>
        /// <param name="branchRepository">BranchRepository dependency, usually this is resolver with IoC</param>
        public BranchManagementService(IBranchRepository branchRepository)
        {
            if (branchRepository == (IBranchRepository)null)
                throw new ArgumentNullException(Resources.Messages.exception_DependenciesAreNotInitialized);

            _BranchRepository = branchRepository;
        }

        #endregion

        public void AddBranch(Branch branch)
        {
            IUnitOfWork unitOfWork = _BranchRepository.UnitOfWork as IUnitOfWork;
            _BranchRepository.Add(branch);
            unitOfWork.Commit();
        }

        public void ChangeBranch(Branch branch)
        {
            IUnitOfWork unitOfWork = _BranchRepository.UnitOfWork as IUnitOfWork;
            _BranchRepository.Modify(branch);
            unitOfWork.CommitAndRefreshChanges();
        }

        public void RemoveBranch(Branch branch)
        {
            if (branch == (Branch)null)
            {
                throw new ArgumentNullException("branch");
            }

            IUnitOfWork unitOfWork = _BranchRepository.UnitOfWork as IUnitOfWork;
            _BranchRepository.Remove(branch);
            unitOfWork.CommitAndRefreshChanges();
        }

        #region IDisposable

        /// <summary>
        /// Dispose associated context with this domain service
        /// </summary>
        public void Dispose()
        {
            if (_BranchRepository != null
                &&
                _BranchRepository.UnitOfWork != null)
            {
                _BranchRepository.UnitOfWork.Dispose();
            }
        }

        #endregion

        public List<Branch> FindPagedBranches(int pageIndex, int pageCount)
        {
            if (pageIndex < 0)
                throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex");

            if (pageCount <= 0)
                throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount");

            Specification<Branch> allSpec = new DirectSpecification<Branch>(c => true);

            return _BranchRepository.GetPagedElements(pageIndex, pageCount, c => c.Name, allSpec, true).ToList();

        }

        public List<Branch> FindBranches(Guid groupBranchId)
        {
            BranchGroupBranchIdSpecification spec = new BranchGroupBranchIdSpecification(groupBranchId);
            return _BranchRepository.FindBranches(spec).ToList();

        }

        public Branch FindBranchByBranchId(Guid branchId)
        {
            BranchBranchIdSpecification spec = new BranchBranchIdSpecification(branchId);
            return _BranchRepository.FindBranch(spec);
        }
    }
}
